package com.mb;

import java.io.IOException;
import java.security.Principal;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.omnifaces.util.Faces;
import org.omnifaces.util.Messages;

import com.facade.UserFacade;
import com.model.User;

@RequestScoped
@ManagedBean
public class UserMB extends AbstractMB {
	
	public static final String HOME_URL = "index.xhtml";
	public static final String LOGIN_URL = "login.xhtml";
	
	private UserMB userMB;
	
	private UserFacade userFacade; 

	private User user;
	private User loggedUser;
	private String username;
	private String password;
	private boolean remember;
	
	public void login() throws IOException{
        try {
            SecurityUtils.getSubject().login(new UsernamePasswordToken(username, password, remember));
            SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(Faces.getRequest());
            Faces.redirect(savedRequest != null ? savedRequest.getRequestUrl() : HOME_URL);
        }
        catch (AuthenticationException e) {
            Messages.addGlobalError("Unknown user, please try again");
            e.printStackTrace(); // TODO: logger.
        }		
	}
	
    public void logout() throws IOException {
		SecurityUtils.getSubject().logout();
		Faces.invalidateSession();
		Faces.redirect(LOGIN_URL);
    }	
    
    public void createUser() {
        try {
        	user.setPassword(new Sha256Hash(user.getPassword()).toHex());
            getUserFacade().create(user);
            Messages.addGlobalInfo("Registration suceed, new user ID is: {0}", user.getId());
        }
        catch (RuntimeException e) {
            Messages.addGlobalError("Registration failed: {0}", e.getMessage());
            e.printStackTrace(); // TODO: logger.
        }
    }

	public void setUserMB(UserMB userMB) {
		this.userMB = userMB;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean isRemember() {
		return remember;
	}

	public void setRemember(boolean remember) {
		this.remember = remember;
	}

	public UserMB getUserMB() {
		return userMB;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}	
	
	public UserFacade getUserFacade() {
		if (userFacade == null) {
			userFacade = new UserFacade();
		}		
		return userFacade;
	}

	public User getUser() {
		if(user == null){
			user = new User();
		}
		
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public User getLoggedUser() {
		
		Subject subject = SecurityUtils.getSubject();
		Session session = subject.getSession();
		if(session.getAttribute("USER") == null){
			loggedUser = getUserFacade().findLoggedUser(subject.getPrincipal().toString());
			subject.getSession().setAttribute("USER", loggedUser);
		}else{
			loggedUser = (User)session.getAttribute("USER");
		}
		
		return loggedUser;
	}

	public void setLoggedUser(User loggedUser) {
		this.loggedUser = loggedUser;
	}
	
	
}